package MysqlUtils

import (
	LogUtils "IMServices/LogService"
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

// MysqlClientInterface 存储系统数据 人员账号密码，系统注册信息，群组信息等
type MysqlClientInterface interface {
	StartMysqlService(ip string, port string, user string, password string, databaseName string)
	databaseInit()
	Insert(sql string)
	SelectUserCache(sql string) map[string]UserData
	SelectOrg(sql string) map[int]DeptData
	queryInsert()
	insert(sql string)
	checkErr(err error)
	release()
}
type MysqlClient struct {
	dbPool       *sql.DB
	mysqlChannel chan string
}

func (m *MysqlClient) StartMysqlService(ip string, port string, user string, password string, databaseName string) error {

	connectStr := user + ":" + password + "@tcp(" + ip + ":" + port + ")/" + databaseName

	pool, openError := sql.Open("mysql", connectStr)
	if openError != nil {
		LogUtils.LogError("database init error = ", openError.Error())
		return openError
	}
	LogUtils.LogInfo(fmt.Sprintf("Mysql服务启动: ip %v", ip) + " port " + port)
	m.dbPool = pool
	m.dbPool.SetMaxOpenConns(100)
	m.dbPool.SetMaxIdleConns(100)
	m.databaseInit()
	m.mysqlChannel = make(chan string, 1000) //带缓存的 channel
	go m.queryInsert()                       //插入采用异步执行，其他同步执行
	return nil
}

func (m *MysqlClient) release() {
	err := m.dbPool.Close()
	if err != nil {
		return
	}
	LogUtils.LogInfo("数据库释放")
}

// DatabaseInit 初始化表格
func (m *MysqlClient) databaseInit() {
	m.insert(CreateUser)
	m.insert(CreateUSerTree)
	m.insert(CreateDept)
}

// Insert 外部调用函数
func (m *MysqlClient) Insert(sql string) {
	m.mysqlChannel <- sql
}

// SelectUserCache 查询
func (m *MysqlClient) SelectUserCache(sql string) map[string]UserData {
	m.dbPool.Query(sql)
	user := make(map[string]UserData)
	return user
}

// SelectModel
func (m *MysqlClient) SelectModel(querySql string, args ...any) *sql.Rows {
	var err error
	var rows *sql.Rows
	if args == nil {
		rows, err = m.dbPool.Query(querySql)
	} else {
		rows, err = m.dbPool.Query(querySql, args)
	}
	if err != nil {
		LogUtils.LogError("查询出现异常，SQL语句为:{},参数为:{}", querySql, args)
		return nil
	}
	return rows
}

// SelectOrg 查询
func (m *MysqlClient) SelectOrg(sql string, args ...any) map[int]DeptData {
	_, err := m.dbPool.Query(sql, args)
	if err != nil {
		LogUtils.LogError("查询出现异常，SQL语句为:{},参数为:{}", sql, args)
		return nil
	}
	depths := make(map[int]DeptData)

	return depths
}

func (m *MysqlClient) queryInsert() {
	for {
		select {
		case sqlStr := <-m.mysqlChannel:
			go m.insert(sqlStr)
		}
	}
}

func (m *MysqlClient) insert(sql string) {
	rows, err := m.dbPool.Query(sql)
	if err != nil {
		LogUtils.LogInfo(err)
		return
	} //
	err = rows.Close()
	if err != nil {
		return
	} //释放连接
}

func (m *MysqlClient) checkErr(err error) {
	if err != nil {
		LogUtils.LogError(err.Error())
	}
}
